package cn.b.sky.user;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class MysecurityContextLogoutHandler implements LogoutHandler {

  private static final Logger log = LoggerFactory.getLogger(LogoutHandler.class);

  private boolean invalidateHttpSession = true;

  private boolean clearAuthentication = true;

  @Override
  public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
    Assert.notNull(request, "HttpServletRequest required");
    if (invalidateHttpSession) {
      HttpSession session = request.getSession(false);
      if (session != null) {
        log.debug("Invalidating session: " + session.getId());
        Object object = session.getAttribute("MANAGEMENT_SECURITY_CONTEXT");
        //废弃老session
        session.invalidate();
        //创建新session
        session =  request.getSession(true);
        session.setAttribute("MANAGEMENT_SECURITY_CONTEXT", object);
      }
    }

    if (clearAuthentication) {
      SecurityContext context = SecurityContextHolder.getContext();
      context.setAuthentication(null);
    }

    SecurityContextHolder.clearContext();

  }

  public boolean isInvalidateHttpSession() {
    return invalidateHttpSession;
  }

  /**
   * Causes the {@link HttpSession} to be invalidated when this {@link LogoutHandler} is invoked. Defaults to true.
   *
   * @param invalidateHttpSession true if you wish the session to be invalidated (default) or false if it should
   * not be.
   */
  public void setInvalidateHttpSession(boolean invalidateHttpSession) {
    this.invalidateHttpSession = invalidateHttpSession;
  }

  /**
   * If true, removes the {@link Authentication} from the {@link SecurityContext} to prevent issues with concurrent
   * requests.
   *
   * @param clearAuthentication true if you wish to clear the {@link Authentication} from the {@link SecurityContext}
   * (default) or false if the {@link Authentication} should not be removed.
   */
  public void setClearAuthentication(boolean clearAuthentication) {
    this.clearAuthentication = clearAuthentication;
  }

}
